﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using coffeeshop.Models;
using System.Drawing.Printing;

namespace coffeeshop.Forms
{
    public partial class frmOrderDetail : Form
    {
        #region "Parameters"
        private System.Resources.ResourceManager mv_Resources = new System.Resources.ResourceManager("coffeeshop.Properties.Resources", System.Reflection.Assembly.GetExecutingAssembly());        
        private coffeeDataSet.ProductDataTable objProductTable = new coffeeDataSet.ProductDataTable();
        private int mySessionNumber;
        public OrderTable objOrderTable { get; set; }
        public int currentWorkTime { get; set; }
        
        private List<OrderDetail> orderedProducts { get; set; } // lưu danh sách những product đã được order trong phiên này
        private Global.OrderType OrderType { get; set; }
        public Form MyParentForm { get; set; }
        #endregion

        #region "Funtions"
        public frmOrderDetail(OrderTable v_objOrderTable, int v_currentWorkTime, Global.OrderType v_orderType)
        {
            InitializeComponent();
            currentWorkTime = v_currentWorkTime;
            OrderType = v_orderType;
            if (v_objOrderTable != null)
            {
                objOrderTable = v_objOrderTable;
                LoadOrderTableDescription();
                LoadWaiterList();
                if (objOrderTable != null)
                { 
                    resetDisplay();
                    mySessionNumber = OrderDetail.getMaxSessionNumber(objOrderTable.TableOrderId);
                    if (OrderType == Global.OrderType.OrderNew)
                    {
                        mySessionNumber = mySessionNumber + 1;
                    }
                }
                else
                {
                    MessageBox.Show(mv_Resources.GetString("ERROR.DISPLAY"));
                }
                
            }            
        }       

        private void LoadOrderTableDescription()
        {
            if (objOrderTable != null)
            {
                objOrderTable = OrderTable.GetTableOrderById(objOrderTable.TableOrderId);
            }
        }

        private void LoadWaiterList()
        {
            lblWaiter.Text = mv_Resources.GetString("FRMORDERDETAIL.WAITER");
            coffeeDataSet.UserDataTable waiterDataList = User.GetPhucVu();
            cboWaiter.DataSource = waiterDataList;
            cboWaiter.ValueMember = "UserId";
            cboWaiter.DisplayMember = "Name";
            cboWaiter.SelectedIndex = -1;
        }

        private void resetDisplay()
        {
            try
            {
                this.Text = mv_Resources.GetString("FRMORDERDETAILNAME") + objOrderTable.TableOrderName;
                lblTableName.Text = mv_Resources.GetString("TABLENAME") + objOrderTable.TableOrderName;
                lblStatus.Text = Global.GetTableOrderStatus(objOrderTable.Status);
                
                objProductTable = Product.GetProductList(true);
                                
                dgvProductList.Columns.Add("Code", mv_Resources.GetString("FRMORDERDETAIL.CODE"));
                dgvProductList.Columns.Add("Name", mv_Resources.GetString("FRMORDERDETAIL.PRODUCT"));
                dgvProductList.Columns.Add("Price", mv_Resources.GetString("FRMORDERDETAIL.PRICE"));
                dgvProductList.Columns.Add("Quantity", mv_Resources.GetString("FRMORDERDETAIL.QUANTITY"));
                dgvProductList.Columns.Add("ProductId", "PRODUCTID");
                dgvProductList.Columns.Add("CompoundProductId", "A");
                dgvProductList.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.Fill;
                dgvProductList.Columns[4].Visible = false;
                dgvProductList.Columns[5].Visible = false;                
                
                // Combobox : filter code of products
                cblFilterCode.DataSource = objProductTable;
                cblFilterCode.DisplayMember = "Code";
                cblFilterCode.ValueMember = "ProductId";
                cblFilterCode.SelectedIndex = -1;

                txtFilterQuantity.Text = "1";
                txtFilterName.Text = "";
                lblFilterCode.Text = mv_Resources.GetString("FRMORDERDETAIL.CODE");
                lblFilterName.Text = mv_Resources.GetString("FRMORDERDETAIL.PRODUCT");
                lblFilterQuantity.Text = mv_Resources.GetString("FRMORDERDETAIL.QUANTITY");
                lblStatusName.Text = mv_Resources.GetString("FRMORDERDETAIL.STATUS").ToUpper();
                lblNotice.Text = mv_Resources.GetString("FRMORDERDETAIL.NOTICE").ToUpper();
                lblSum.Text = mv_Resources.GetString("FRMORDERDETAIL.SUM").ToUpper();
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }

        private bool onSave()
        {
            bool blnResult = false;            
            try
            {               
                OrderDetail saveOrderDetail = new OrderDetail(); 
                foreach (DataGridViewRow iRow in dgvProductList.Rows)
                {
                    blnResult = insertOrderDetail(iRow);
                    if (blnResult)
                    {
                        blnResult = insertSaleProduct(iRow);
                        if (!blnResult)
                        {
                            break;
                        }
                    }
                    else
                    {
                        break;
                    }                    
                }
                if (blnResult)
                {
                    // Update Status of Table (don't process if return order)
                    if (OrderType != Global.OrderType.OrderReturn)
                    {
                        blnResult = blnResult & updateOrderTableStatus(); 
                    }                    
                }                               
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
                blnResult = false;
            }
            return blnResult;
        }

        private bool updateOrderTableStatus()
        {
            OrderTable saveOrderTable = new OrderTable();

            switch (objOrderTable.Status)
            {
                case Global.TableStatus.Available:
                    objOrderTable.Status = Global.TableStatus.Servicing;
                    break;
                case Global.TableStatus.Billed:
                    objOrderTable.Status = Global.TableStatus.Changed;
                    break;
                default:
                    break;
            }
            saveOrderTable.TableOrderId = objOrderTable.TableOrderId;
            saveOrderTable.TableOrderName = objOrderTable.TableOrderName;
            saveOrderTable.Status = objOrderTable.Status;
            saveOrderTable.IsActive = objOrderTable.IsActive;
            
            return saveOrderTable.updateOrderTable();
        }

        private bool insertOrderDetail(DataGridViewRow aRow)
        {
            OrderDetail saveOrderDetail = new OrderDetail();
            saveOrderDetail.OrderTableId = objOrderTable.TableOrderId;
            saveOrderDetail.ProductId = Convert.ToInt16(aRow.Cells[4].Value);
            if (OrderType != Global.OrderType.OrderReturn)
            {
                saveOrderDetail.Quantity = Convert.ToInt16(aRow.Cells[3].Value);
            }
            else
            {
                saveOrderDetail.Quantity = Convert.ToInt16(aRow.Cells[3].Value) * -1;
            }            
            saveOrderDetail.SessionNumber = mySessionNumber;
            saveOrderDetail.OrderedBy = Convert.ToInt16(cboWaiter.SelectedValue);
            saveOrderDetail.ProductName = aRow.Cells[1].Value.ToString();

            if (orderedProducts == null)
                orderedProducts = new List<OrderDetail>();            
            orderedProducts.Add(saveOrderDetail);

            return saveOrderDetail.insertOrderDetail();
        }

        private bool insertSaleProduct (DataGridViewRow aRow)
        {
            SaleProduct saveSaleProduct = new SaleProduct();
            saveSaleProduct.ProductId = Convert.ToInt16(aRow.Cells[4].Value);
            saveSaleProduct.WorkTimeId = currentWorkTime;
            if (OrderType != Global.OrderType.OrderReturn)
            {
                saveSaleProduct.Quantity = Convert.ToDouble(aRow.Cells[3].Value);
            }
            else
            {
                saveSaleProduct.Quantity = Convert.ToDouble(aRow.Cells[3].Value) * -1;
            }
            saveSaleProduct.OrderType = OrderType;
            saveSaleProduct.Price = Convert.ToInt32(aRow.Cells[2].Value.ToString().Replace(",",""));            
            saveSaleProduct.TableId = objOrderTable.TableOrderId;
            saveSaleProduct.CompoundProductId = Convert.ToInt32(aRow.Cells[5].Value);

            return saveSaleProduct.insertSaleProduct();
        }

        // Print ordered bill to send to kitchen. 
        private void onPrint()
        {
            foreach (var printer in PrinterSettings.InstalledPrinters)
            {
                var settings = new PrinterSettings();
                settings.PrinterName = printer.ToString();

                if (settings.IsDefaultPrinter)
                {
                    //MessageBox.Show("the default printer is: " + settings.DefaultPageSettings.PaperSize.Width.ToString());
                    PrintDocument pdoc = new PrintDocument();
                    pdoc.DefaultPageSettings.PaperSize = settings.DefaultPageSettings.PaperSize;
                    pdoc.PrintPage += new PrintPageEventHandler(pdoc_PrintPage);
                    pdoc.Print();
                    return;
                }
            }

            MessageBox.Show("Bạn chưa cài đặt máy in mặc định. Vui lòng cài đặt một máy in mặc định trước khi in");
        }

        void pdoc_PrintPage(object sender, PrintPageEventArgs e)
        {
            Graphics graphics = e.Graphics;
            PrintDocument pdoc = (PrintDocument)sender;                        
            string currentCalam = "";
            if (OrderType == Global.OrderType.OrderNew)
            {
                frmListTables parentFormOrder = (frmListTables)MyParentForm;
                currentCalam = parentFormOrder.CaLam;
            }
            else
            {
                frmOrderCurrentTable parentFormReturn = (frmOrderCurrentTable)MyParentForm;
                currentCalam = parentFormReturn.CaLam;                
            }
  
            int paperWidth = pdoc.DefaultPageSettings.PaperSize.Width;
            int startX = 50;
            int startY = 0;
            int offset = 40;

            graphics.DrawString("PHIẾU: " + Global.GetOrderTypeText(OrderType), new Font("Courier New", 14, FontStyle.Bold),
                                new SolidBrush(Color.Black), startX, startY + offset);
            offset = offset + 20;
            graphics.DrawString("Bàn: " + objOrderTable.TableOrderName,
                     new Font("Courier New", 14, FontStyle.Bold),
                     new SolidBrush(Color.Black), startX, startY + offset);
            graphics.DrawString("CA: " + currentCalam,
                     new Font("Courier New", 14),
                     new SolidBrush(Color.Black), paperWidth - 2 * startX, startY + offset);

            offset = offset + 20;
            graphics.DrawString("Phục vụ: " + cboWaiter.SelectedText,
                     new Font("Courier New", 14, FontStyle.Bold),
                     new SolidBrush(Color.Black), startX, startY + offset);
            
            offset = offset + 20;
            graphics.DrawString("Thời gian: " + DateTime.Now.ToString("dd/MM/yyyy - HH:MM:ss"),
                     new Font("Courier New", 14, FontStyle.Bold),
                     new SolidBrush(Color.Black), startX, startY + offset);

            offset = offset + 20;
            string underLine = "------------------------------------------";
            graphics.DrawString(underLine, new Font("Courier New", 10),
                     new SolidBrush(Color.Black), startX, startY +offset);

            offset = offset + 20;
            foreach (OrderDetail od in orderedProducts)
            {
                offset = offset + 20;

                graphics.DrawString(od.ProductName, new Font("Courier New", 12),
                     new SolidBrush(Color.Black), startX, startY + offset);
                graphics.DrawString(od.Quantity.ToString(), new Font("Courier New", 12),
                     new SolidBrush(Color.Black), paperWidth - startX, startY + offset);
            }
        }
              
        protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
        {
            if (keyData == Keys.F12)
            {

                if (onSave())
                {
                    if (OrderType == Global.OrderType.OrderReturn)
                    {
                         MessageBox.Show(mv_Resources.GetString("FRMORDERDETAIL.RETURNSUCCESS"),mv_Resources.GetString("FRMORDERDETAIL.MSGTITLE") ,
                                    MessageBoxButtons.OK,MessageBoxIcon.Information,MessageBoxDefaultButton.Button1);
                    }
                    else
                    {
                        MessageBox.Show(mv_Resources.GetString("FRMORDERDETAIL.ADDSUCCESS"), mv_Resources.GetString("FRMORDERDETAIL.MSGTITLE"),
                                    MessageBoxButtons.OK, MessageBoxIcon.Information, MessageBoxDefaultButton.Button1);
                    }                    
                    onPrint();
                    this.Close();
                }
                else
                {
                    MessageBox.Show(mv_Resources.GetString("FRMORDERDETAIL.FAILURE"), mv_Resources.GetString("FRMORDERDETAIL.MSGTITLE"), 
                                    MessageBoxButtons.OK, MessageBoxIcon.Error, MessageBoxDefaultButton.Button1);                    
                }
                return true;
            }
            return base.ProcessCmdKey(ref msg, keyData);
        }        
        private void addNewOrderToOrderList()
        {
            double dblPrice = 0;

            DataGridViewRow aRow = new DataGridViewRow();
            aRow.CreateCells(dgvProductList);
            aRow.Cells[0].Value = objProductTable.Rows[cblFilterCode.SelectedIndex]["Code"].ToString();
            aRow.Cells[1].Value = txtFilterName.Text;
            dblPrice = Convert.ToDouble(objProductTable.Rows[cblFilterCode.SelectedIndex]["Price"]);
            aRow.Cells[2].Value = dblPrice.ToString("#,##0");
            aRow.Cells[3].Value = txtFilterQuantity.Text;
            aRow.Cells[4].Value = objProductTable.Rows[cblFilterCode.SelectedIndex]["ProductId"].ToString();
            aRow.Cells[5].Value = objProductTable.Rows[cblFilterCode.SelectedIndex]["CompoundProductId"].ToString();
            dgvProductList.Rows.Add(aRow);
        }

        #endregion

        #region "Events"
        private void cblFilterCode_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (cblFilterCode.SelectedIndex >= 0)
            {
                txtFilterName.Text = objProductTable.Rows[cblFilterCode.SelectedIndex]["Name"].ToString();
                txtFilterQuantity.Text = "1";

                foreach (DataGridViewRow iRow in dgvProductList.Rows)
                {
                    if (iRow.Cells[0].Value == objProductTable.Rows[cblFilterCode.SelectedIndex]["Code"])
                    {    
                        txtFilterQuantity.Text = iRow.Cells[3].Value.ToString();
                        iRow.Selected = true ;
                        txtFilterQuantity.Focus();
                        break;
                    }
                    else
                    {
                        iRow.Selected = false;
                    }
                }
            }
        }

        private void txtFilterQuantity_Validating(object sender, CancelEventArgs e)
        {
            Boolean isExist = false;
            double dblSum = 0;
            try
            {
                if (cblFilterCode.SelectedIndex >= 0)
                {
                    // Update quanlity: only do for the first order.
                    foreach (DataGridViewRow iRow in dgvProductList.Rows)
                    {
                        if (iRow.Cells[0].Value == objProductTable.Rows[cblFilterCode.SelectedIndex]["Code"])
                        {
                            isExist = true;                            
                            if (Convert.ToInt16(txtFilterQuantity.Text.Trim()) > 0)
                            {
                                iRow.Cells[3].Value = txtFilterQuantity.Text;
                            }
                            else  // Remove order
                            {
                                dgvProductList.Rows.Remove(iRow);
                                cblFilterCode.SelectedIndex = -1;
                                txtFilterQuantity.Text = "1";
                            }
                            break;
                        }
                    }

                    // add one more order
                    if (!isExist)
                    {
                        if (Convert.ToInt16(txtFilterQuantity.Text.Trim()) > 0)
                        {
                            addNewOrderToOrderList();
                        }
                        else
                        {
                            MessageBox.Show(mv_Resources.GetString("FRMORDERDETAIL.CHECKQUANTITY"), mv_Resources.GetString("FRMORDERDETAIL.MSGTITLE"), 
                                            MessageBoxButtons.OK, MessageBoxIcon.Error, MessageBoxDefaultButton.Button1);
                            txtFilterQuantity.Focus();
                        }
                    }
                    // Summarize total
                    foreach (DataGridViewRow jRow in dgvProductList.Rows)
                    {
                        dblSum = dblSum + Convert.ToDouble(jRow.Cells[2].Value) * Convert.ToDouble(jRow.Cells[3].Value);
                    }

                    txtSum.Text = dblSum.ToString("$#,##0");
                }

            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }

        private void txtFilterQuantity_Enter(object sender, EventArgs e)
        {
            txtFilterQuantity.SelectAll();
        }

        private void dgvProductList_CellClick(object sender, DataGridViewCellEventArgs e)
        {
            cblFilterCode.SelectedValue = dgvProductList.Rows[e.RowIndex].Cells[4].Value;
        }

        #endregion         
    }
}
